<?php
namespace Think;
/**
 *HTML5文件上传类
 */
class Html5Upload
{
    /**
     * 默认上传配置
     */
    private $config = array(
        'subName'       =>  array('date', 'Y-m-d'), //子目录创建方式，[0]-函数名，[1]-参数，多个参数使用数组
        'rootPath'      =>  './Uploads/', //保存根路径
        'subPath'      =>  '',  //子目录路径
        'tokenPath'     => './Uploads/tokens/',
        'saveName'      =>  array('uniqid', ''), //上传文件命名规则，[0]-函数名，[1]-参数，多个参数使用数组
        'driverConfig'  =>  array(), // 上传驱动配置
    );
    private $_picParam=array();    //上传图片的参数
    public function __construct($_picParam = array(),$config=array()){
        /* 获取配置 */
        $this->_picParam   =   array_merge($this->_picParam, $_picParam); //图片本身信息参数
        $this->config   =   array_merge($this->config, $config); //自定义图片参数
        if(!is_dir($this->config['tokenPath'])){  //创建token 目录
            mkdir($this->config['tokenPath'], 0700);
        }
    }
    /**
	 *创建文件上传信息���
	 */
	public function tk(){
        $file['name'] = $this->_picParam['name'];
        $file['size'] = $this->_picParam['size'];
        $file['token'] = md5(json_encode($file['name'] . $file['size']));
		if(! file_exists($this->config['tokenPath'] . $file['token'] . '.token')){
            $file['up_size'] = 0;
			$pathInfo = pathinfo($file['name']);
            $path =$this->config['rootPath'] . date('Ymd') .'/';
            if(!empty($this->config['subPath'])){
                $path =$this->config['rootPath'] .$this->config['subPath'];
            }
			if(!is_dir($path)){  //判断文件夹是否存在
				mkdir($path, 0700);
			}
			//文件的保存路径
            $file['saveName']=$file['token'] .'.'. $pathInfo['extension'];
            $file['filePath'] = $path . $file['token'] .'.'. $pathInfo['extension'];
            $file['modified'] = $this->_picParam['modified'];   //文件缓存信息
            $file=array_merge($file,$pathInfo);
			$this->setTokenInfo($file['token'],$file);
		}
		$result['token'] =$file['token'];
		$result['success'] = true;
        $result['msg'] ='文件token创建成功';
		return $result;
		exit;
	}
	
	/**
	 *上传文件
	 */
	public function up(){
        $result['status']=0;  //失败
		if('html5' == $this->_picParam['client']){
            $result=$this->html5Upload();  //HTML
            $result['status']=1;
		}elseif('form' == $this->_picParam['client']){
            $result=$this->flashUpload();
            $result['status']=1;
		}else{
            $result=array('start'=>0,'msg'=>'上传方式选择参数有误!');
		}
		return $result;
	}
	
	/**
	 * HTML5�
	 */
	protected function html5Upload(){
		$token = $this->_picParam['token'];
		$fileInfo = $this->getTokenInfo($token);
		if($fileInfo['size'] > $fileInfo['up_size']){
			$data = file_get_contents('php://input', 'r');
			if(! empty($data)){
				$fp = fopen($fileInfo['filePath'], 'a');
				flock($fp, LOCK_EX);
				fwrite($fp, $data);
				flock($fp, LOCK_UN);
				fclose($fp);
				$fileInfo['up_size'] += strlen($data);
				if($fileInfo['size'] > $fileInfo['up_size']){
					$this->setTokenInfo($token, $fileInfo);
				}else {
                    @unlink($this->config['tokenPath'] . $token . '.token');
                }
			}
		}
		$result['start'] =$fileInfo['up_size'];
        $result['success'] = true;
        $result['info']=$fileInfo;
        return $result;
	}
	
	/**
	 *flash上传
	 */
	public function flashUpload(){
        $result['start']=0;
		$result['success'] = false;
        $result['msg']='php暂不支持Flash方式上传!';
	    return $result;
		exit;
	}
	
	/**
	 *设置断点上传的token ��
	 */
	protected function setTokenInfo($token, $data){
		file_put_contents($this->config['tokenPath'] . $token . '.token', json_encode($data));
	}

	/**
	 *获取token �
	 */
	protected function getTokenInfo($token){
		$file = $this->config['tokenPath'] . $token . '.token';
		if(file_exists($file)){
			return json_decode(file_get_contents($file), true);
		}
		return false;
	}
}